package web.exception;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description 全局异常捕获类
 * 博客地址：https://www.jianshu.com/p/2432d0f51c0e
 * @Author lishengpeng
 * @Date 2023/2/21 17:09
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandle {

    /**
     * 参数绑定异常处理
     */
    @ResponseBody
    @ExceptionHandler({BindException.class, ConstraintViolationException.class, MethodArgumentTypeMismatchException.class})
    public String bindExceptionHandler(BindException e) {
        log.info("参数绑定错误：{}", e.getMessage(), e);
        if (e.getBindingResult().hasErrors()) {
            return String.format("参数[%s]]赋值错误，请参考接口文档", getValidateMsg(e.getBindingResult()));
        }
        return "参数绑定错误";
    }

    /**
     * 信息格式化
     *
     * @param bindingResult bind
     * @return String
     * @author lisp
     **/
    private String getValidateMsg(BindingResult bindingResult) {
        Map<String, String> map = new HashMap<>();
        bindingResult.getFieldErrors().stream().forEach(item -> {
            String field = item.getField();
            String defaultMessage = item.getDefaultMessage();
            map.put(field, defaultMessage);
        });
        return JSONObject.toJSONString(map);
    }

    /**
     * 用于业务层异常处理的方法
     */
    @ResponseBody
    @ExceptionHandler(BaseException.class)
    public String serviceErrorExceptionHandler(BaseException e) {
        log.error("自定义业务异常：{}", e.getMessage());
        return "抛出自定义业务异常";
    }

    /**
     * 用于所有异常处理的方法
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public String exceptionHandler(Exception e) {
        log.error("系统异常：{}", e.getMessage(), e);
        return "系统异常";
    }
}
